package com.yylc.cscore.service.impl;

import cn.hutool.core.util.StrUtil;
import com.yylc.cscore.bean.TaskRuleBean;
import com.yylc.cscore.bean.base.PageBean;
import com.yylc.cscore.component.JobScheduler;
import com.yylc.cscore.component.JobTrigger;
import com.yylc.cscore.dao.TaskRuleDao;
import com.yylc.cscore.entity.TaskRuleEntity;
import com.yylc.cscore.service.CustomerService;
import com.yylc.cscore.service.TaskRuleService;
import com.yylc.cscore.service.TaskTypeService;
import com.yylc.cscore.util.PageUtil;
import com.yylc.cscore.util.R;
import com.yylc.cscore.util.YYlcBeanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author xiangnan
 * date 2018/5/2
 */
@Service
public class TaskRuleServiceImpl implements TaskRuleService {
    private static final Logger logger = LogManager.getLogger();

    @Resource
    private CustomerService customerService;

    @Resource
    private TaskTypeService taskTypeService;

    @Resource
    private TaskRuleDao taskRuleDao;

    @Resource
    private JobScheduler jobScheduler;

    @Resource
    private JobTrigger jobTrigger;

    @Override
    public PageBean<TaskRuleBean> getTaskRuleList(int type, int current, int pageSize) {
        int total = taskRuleDao.selectPageListCount(R.ruleType.FEN_PEI);
        if (!PageUtil.check(current, total, pageSize)) {
            throw new RuntimeException("页数错误");
        }

        List<TaskRuleEntity> entityList = taskRuleDao.selectPageList(type, PageUtil.getStart(current, pageSize), pageSize);
        List<TaskRuleBean> beanList = new ArrayList<>();
        entityList.forEach(entity -> beanList.add(YYlcBeanUtils.copyProperties(entity, new TaskRuleBean())));

        // 获取客服人员列表和任务类型列表
        beanList.forEach(bean -> {
            bean.setServiceList(customerService.getCustomerList(bean.getAllotServiceId()));
            bean.setTaskTypeList(taskTypeService.getTaskTypeList(bean.getAllotTaskCode()));
        });

        return new PageBean<>(current, pageSize, total, beanList);
    }

    @Override
    @Transactional
    public int addTaskRule(TaskRuleBean bean) {
        TaskRuleEntity entity = YYlcBeanUtils.copyProperties(bean, new TaskRuleEntity());
        entity.setType(R.ruleType.FEN_PEI);

        logger.info("addTaskRule: {}", entity);
        taskRuleDao.insert(entity);

        if (jobScheduler.exists(String.valueOf(entity.getId()), String.valueOf(entity.getId()))) {
            throw new RuntimeException(bean.getId() + " 任务已存在");
        }
        logger.info("addTaskRule: {} success", entity);
        return 0;
    }

    @Override
    @Transactional
    public int updateTaskRule(TaskRuleBean bean) {
        TaskRuleEntity entity = YYlcBeanUtils.copyProperties(bean, new TaskRuleEntity());
        TaskRuleEntity oldEntity = taskRuleDao.selectById(entity.getId());
        if (oldEntity == null) {
            throw new RuntimeException("未找到该任务规则");
        }

        logger.info("updateTaskRule: {}", entity);

        taskRuleDao.update(entity);

        if (!StrUtil.equals(oldEntity.getAutoAllotTime(), entity.getAutoAllotTime())) {
            String name = String.valueOf(entity.getId());
            String group = String.valueOf(entity.getId());
            jobScheduler.deleteJob(name, group);
            if (entity.getStatus() == R.taskRuleStatus.RUNNING) {
                jobScheduler.addJob(name, group, bean.getAutoAllotTime());
            }
        }

        logger.info("updateTaskRule: {} success", entity);
        return 0;
    }

    /**
     * status: 1 表示生效， 0 表示失效
     */
    @Override
    @Transactional
    public int updateTaskRule(int status, int id) {
        logger.info("updateTaskRule: id={}, status={}", id, status);
        TaskRuleEntity entity = taskRuleDao.selectById(id);
        if (entity == null) {
            throw new RuntimeException("未找到任务规则");
        }

        taskRuleDao.update(new TaskRuleEntity(id, status));

        String name = String.valueOf(entity.getId());
        String group = String.valueOf(entity.getId());
        if (status == R.taskRuleStatus.RUNNING) {
            // 使能任务规则
            if (jobScheduler.exists(name, group)) {
                jobScheduler.resumeJob(name, group);
            } else {
                jobScheduler.addJob(name, group, entity.getAutoAllotTime());
            }
        } else if (status == R.taskRuleStatus.INIT) {
            // 暂停任务规则
            jobScheduler.pauseJob(name, group);
        }

        logger.info("updateTaskRule: id={}, status={} success", id, status);
        return 0;
    }

    @Override
    @Transactional
    public int deleteTaskRule(TaskRuleBean bean) {
        TaskRuleEntity entity = YYlcBeanUtils.copyProperties(bean, new TaskRuleEntity());

        logger.info("deleteTaskRule: {}", entity);
        if (entity.getStatus() != R.taskRuleStatus.DELETE) {
            entity.setStatus(R.taskRuleStatus.DELETE);
            taskRuleDao.update(entity);
        }

        jobScheduler.deleteJob(String.valueOf(entity.getId()), String.valueOf(entity.getId()));
        logger.info("deleteTaskRule: {} success", entity);
        return 0;
    }

    @Override
    public int triggerTaskRule(int id) {
        TaskRuleEntity entity = taskRuleDao.selectById(id);
        if (entity == null) {
            logger.error("未找到任务规则，id={}", id);
            throw new RuntimeException("未找到任务规则");
        }

        jobScheduler.triggerJob(String.valueOf(entity.getId()), String.valueOf(entity.getId()));
        return 0;
    }

    @Override
    public int artificialTriggerTaskRule(TaskRuleBean bean, String userIdList) {
        if (StrUtil.isBlank(userIdList)) {
            jobTrigger.triggerInternal(YYlcBeanUtils.copyProperties(bean, new TaskRuleEntity()), new Date());
        } else {
            jobTrigger.triggerInternal(YYlcBeanUtils.copyProperties(bean, new TaskRuleEntity()), new Date(), userIdList);
        }

        return 0;
    }

}
